/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2004
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
*
* Author's email : insane@dees.ufmg.br
* Author's Website : http://www.dees.ufmg.br/insane
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
package br.ufmg.dees.insane.model.xfemModel.phenomenaDetector;

import java.util.ListIterator;

import br.ufmg.dees.insane.materialMedia.degeneration.Degeneration;
import br.ufmg.dees.insane.model.xfemModel.xfemElement.XFEMElement;
import br.ufmg.dees.insane.util.IMatrix;
import br.ufmg.dees.insane.util.IVector;
import br.ufmg.dees.insane.util.xfem.IEigenvalueDecomposition;

/**
 * @author Kelson Wolff
 *
 */
public class CohesiveCrackPropagation extends PhenomenaDetector {
	
	/**
	 * Comment for <code>serialVersionUID</code>
	 */
	private static final long serialVersionUID = 1L;
	
	/**
	 * The tensile strength of the material.
	 */
	private double tensileStrength;
	
	public CohesiveCrackPropagation() {
		//this.problemDriver = new CohesiveCrackProblemDriver();
		//this.shape = new Heaviside();
		//this.constModel = new WellsSluysCrackingModel();
	}

	/**
	 * @return Returns the tensileStrength.
	 */
	public double getTensileStrength() {
		return tensileStrength;
	}

	/**
	 * @param tensileStrength The tensileStrength to set.
	 */
	public void setTensileStrength(double tensileStrength) {
		this.tensileStrength = tensileStrength;
	}

//	@Override
//	public void enrichElement(XFEMElement e){
//		if (e.isEnriched()) {
//			
//		} 
//		else {
//			if(this.verifyPhenomenon(e)){
//				e.setMyProblemDriver(this.problemDriver);
////				e.setEnrichItem(this.enrichmentItem);
//				e.setShape(this.shape);
////				e.setEnriched(true);
//			}
//		}	
//	}
	
	/**
	 * Verifies if the tensile strength limit is reached in each
	 * degeneration point that belong to provided XFEMElement elm.
	 * If this limit is reached, the crack is allowed to carry its
	 * propagation out. 
	 * @param elm The provided XFEMElement.
	 * @return True if tensile strength limit is reached in any
	 * degeneration point that belong to provided XFEMElement elm
	 * and false if it isn't reached.
	 */
	public boolean verifyPhenomenonOccurrence(XFEMElement elm) {
		ListIterator dgns = elm.getDegenerations().listIterator();
			while(dgns.hasNext()){
			    Degeneration dg = (Degeneration)dgns.next();
			    IVector stresses = elm.getDegenerationDualInternalVariables(dg);
			    IMatrix stressTensor = elm.getAnalysisModel().expandTensor(stresses);
			    IEigenvalueDecomposition eigenValues = new IEigenvalueDecomposition(stressTensor);
			    IMatrix principalStresses = eigenValues.getD();
			    for(int i = 0; i<principalStresses.getNumRow(); i++)
					for(int j = 0; j<principalStresses.getNumCol(); j++)
						if(i == j){
							if(principalStresses.getElement(i,j) >= this.tensileStrength) {
								return true;
							}
						}
						
			}	        
		return false;
	}
}
